const Server = require('./base-server')
const logger = require('../console-logger')
const { doRequest } = require('../http-utils')

class JellyfinServer extends Server {
  constructor(config) {
    super(config)
    this.serverType = 'jellyfin'
  }

  async setup(setConfig) {

    // default
    this.serverHost = "" 
    this.apikey = ""
    
    if (setConfig) {
      setConfig.host && (this.serverHost =  setConfig.host);
      setConfig.apiKey &&  (this.apikey =  setConfig.apiKey);
    }
    if (this.serverHost && this.apikey) {
      const adminUser = await this.getAdminUser();
      if (adminUser && adminUser.Id) {
        this.adminUserId = adminUser.Id
        logger.info('Jellyfin 服务启动成功');
      } else {
        logger.info('Jellyfin 服务启动失败');
      }
    } else {
      logger.info('Jellyfin 服务器未配置');
    }
  }

  call(options) {
    if (!this.serverHost || !this.apikey)
      throw new Error('Jellyfin 服务器未配置');

    const requestOptions = {
      method: options.method || 'get',
      url: options.url,
      baseURL: this.serverHost,
      params: {
        api_key: this.apikey,
        ...options.params,
      },
      timeout: 10000,
    }

    if (options.data) {
      requestOptions.data = options.data 
    }

    return new Promise((resolve, reject) => {
      doRequest(requestOptions)
        .then(function (response) {
          resolve(response);
        })
        .catch(function (error) {
          // reject(error);
          logger.error('doRequest error: ', error)
          resolve(null);
        })
    });
  }

  async getAdminUser() {
    const res = await this.call({
      url: '/Users',
    })
    logger.debug('getAdminUser res: ', res)
    if (res)
      return res.find(item => item.Policy.IsAdministrator)
  }

  async getStatus() {
    const res = await this.instance.getSession()
    logger.debug('getSetting res: ', res)
    if (res.result === 'success')
      return {
        version: res.arguments.version,
        downloadDir: res.arguments['download-dir']
      }
    else
      return {}
  }

  async getActivityLog(num) {
    const res = await this.call({
      url: '/System/ActivityLog/Entries',
      params: {
        Limit: num,
      }
    })
    logger.debug('getActivityLog res: ', res)
    return res
  }

  async getMediasCount() {
    const res = await this.call({
      url: '/Items/Counts',
    })
    logger.debug('getMediasCount res: ', res)
    return res
  }

  // 根据名称获取Jellyfin剧Id
  async getSeriesIdByName(title, year) {
    const res = await this.call({
      url: '/Items',
      params: {
        userId: this.adminUserId,
        includeItemTypes: 'Series',
        limit: 10,
        recursive: true,
        enableUserData: false,
        enableImages: false,
        searchTerm: title,
      }
    })
    logger.debug('getSeriesIdByName res: ', res)
    if (res) {
      const series = res.Items.find(item => item.Name === title && (!year || item.ProductionYear === parseInt(year)))
      if (series)
        return series.Id
    }


  }

  // 根据名称获取Jellyfin季Id
  async getSeasonIdByName(title, year, season = 1) {
    const seriesId = await this.getSeriesIdByName(title, year)
    if (seriesId) {
      const res = await this.call({
        url: `/Shows/${seriesId}/Seasons`,
        params: {
          userId: this.adminUserId,
        }
      })
      logger.debug('getSeasonIdByName res: ', res)

      if (res) {
        const seasonItem = res.Items.find(item => item.IndexNumber === parseInt(season))
        if (seasonItem)
          return {
            seriesId,
            seasonId: seasonItem.Id,
          }
      }
    }

    return {
    }
  }

  // 获取某一季Jellyfin已存在的集
  async getTvEpisodes(title, year, season) {
    const { seriesId, seasonId } = await this.getSeasonIdByName(title, year, season)
    if (seriesId && seasonId) {
      const res = await this.call({
        url: `/Shows/${seriesId}/Episodes`,
        params: {
          userId: this.adminUserId,
          seasonId: seasonId,
          isMissing: false,
        }
      })
      logger.debug('getTvEpisodes res: ', res)
      if (res) {
        return res.Items.map(item => item.IndexNumber)
      }
    }
    return []
  }

  // 获取某一季Jellyfin不存在的集
  async getNoExistsTvEpisodes(title, year, season, episodeCount) {
    const existsEpisodes = await this.getTvEpisodes(title, year, season)
    const allEpisodes = Array.from({ length: episodeCount }, (v, k) => k + 1)
    return allEpisodes.filter(episode => !existsEpisodes.includes(episode))
  }

  // 查询电影列表
  async searchMovie(title, year) {
    const res = await this.call({
      url: '/Items',
      params: {
        userId: this.adminUserId,
        includeItemTypes: 'Movie',
        isFolder: false,
        limit: 10,
        recursive: true,
        enableUserData: false,
        enableImages: false,
        searchTerm: title,
      }
    })
    logger.debug('searchMovie res: ', res)
    return res
  }

  // 获取单个电影信息
  async getMovie(title, year) {
    const res = await this.searchMovie(title, year)
    if (res) {
      return res.Items.find(item => item.Name === title && (!year || item.ProductionYear === parseInt(year)))
        // .map(item => ({
        //   title: item.Name,
        //   year: item.ProductionYear,
        // }))
    }
  }

  // 获取媒体库
  async getLibrarys() {
    const res = await this.call({
      url: '/Libraries/AvailableOptions', // MediaFolders PhysicalPaths AvailableOptions http://localhost/Libraries/AvailableOptions
      // params: {
      //   userId: this.adminUserId,
      //   includeItemTypes: 'Series',
      //   limit: 10,
      //   recursive: true,
      //   searchTerm: title,
      // }
    })
    logger.debug('getLibrarys res: ', res)
  }
}

module.exports = new JellyfinServer();